home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 44
/
Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso
/
Aminet
/
comm
/
misc
/
Sashi89.lha
/
Sashi89
/
sources
/
hard.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-05-08
|
10KB
|
515 lines
/*
This file handle the low-level communication.
It supports both usual Parallel port and the $4 serial link.
Just put HARD_VERSION = HARD_VERSION_PAR or HARD_VERSION_SER
to switch between them
*/
//#define DEBUG
//#define STAT
#define HARD_VERSION_PAR 1
#define HARD_VERSION_SER 2
#define HARD_VERSION HARD_VERSION_SER
#include <stdio.h>
#include <stdlib.h>
/* Amiga */
/* Hardware : */
#include <exec/types.h>
#include <hardware/cia.h>
/* System : */
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <devices/serial.h>
#include <devices/parallel.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include "hard.h"
/* Two lines between computer and calc : */
#define LINE1 1
#define LINE2 2
#if HARD_VERSION == HARD_VERSION_SER
#elif HARD_VERSION == HARD_VERSION_PAR
#endif
/* Two states for each line : */
#define HIGH 0
#define LOW 1
/* Assert a state on a line : */
inline void ti_setline(int value, UBYTE where);
/* Get state of a line : */
inline UBYTE ti_getline(UBYTE where);
/* Amiga Specific : */
extern struct CIA ciaa, ciab;
struct MsgPort *SerialMP=NULL; /* Message port pointer */
struct IOExtSer *SerialIO=NULL; /* I/O request pointer */
struct MsgPort *ParallelMP=NULL; /* Message port pointer */
struct IOExtPar *ParallelIO=NULL; /* I/O request pointer */
/* Keep state in static, so that we can remember what we did at init,
and what we didn't
*/
static int state=0;
#define STATE_PORT 1
#define STATE_EXTIO 2
#define STATE_DEV 4
/*
Timer stuff
We use timer only for timeout or retry delays
*/
#include "timer.h"
Timer_Info time_info;
#define HARD_MAX_TRY_ACTIVE 100
#define HARD_MAX_TRY (HARD_MAX_TRY_ACTIVE+30)
/* Wait after retrying, if the calc. does not ack enough quickly */
#define WAIT_RETR timer_delay(&time_info,10000)
/* Wait if a timeout occures : */
#define WAIT_TIMEOUT timer_delay(&time_info,200000)
/*
if debug_mode == 0 then we are system compliant : ask for device
Otherwise, we are not
*/
extern int debug_mode;
char *ti_version(void )
{
#if HARD_VERSION == HARD_VERSION_SER
return("serial version ("__DATE__")");
#elif HARD_VERSION == HARD_VERSION_PAR
return("parallel version ("__DATE__")");
#endif
}
int ti_openport(void )
{
if ( ! debug_mode )
{
#if HARD_VERSION == HARD_VERSION_SER
/* Ask for the serial port */
if ( !( SerialMP=CreatePort(NULL,0)) )
{
printf(__FILE__"> CreatePort failed.\n");
ti_closeport();
return(1);
}
state += STATE_PORT;
if ( !( SerialIO=(struct IOExtSer *)CreateExtIO(SerialMP,sizeof(struct IOExtSer)) ) )
{
printf(__FILE__"> Unable to open SerialIO.\n");
ti_closeport();
return(1);
}
state += STATE_EXTIO;
if ( OpenDevice(SERIALNAME,0L,(struct IORequest *)SerialIO,0))
{
printf(__FILE__"> Unable to open serial port ( %s unit 0 )\n",SERIALNAME);
ti_closeport();
return(1);
}
state += STATE_DEV;
#elif HARD_VERSION == HARD_VERSION_PAR
/* Ask for the parallel port */
if ( ! ( ParallelMP=CreatePort(NULL,0) ) )
{
printf(__FILE__"> CreatePort failed.\n");
ti_closeport();
return(1);
}
state += STATE_PORT;
if ( ! ( ParallelIO=(struct IOExtPar *)CreateExtIO(ParallelMP,sizeof(struct IOExtPar)) ) )
{
printf(__FILE__"> Unable to open ParallelIO.\n");
ti_closeport();
return(1);
}
state += STATE_EXTIO;
if (OpenDevice(PARALLELNAME,0L,(struct IORequest *)ParallelIO,0) )
{
printf(__FILE__"> Unable to open parallel port ( %s unit 0 )\n",PARALLELNAME);
ti_closeport();
return(1);
}
state += STATE_DEV;
#endif
}
/* We now have the serial or paralle device for ourselves */
ti_initport();
if ( timer_create(&time_info) )
{
printf(__FILE__"> Error creating timer\n");
ti_closeport();
return(1);
}
return(0); /* No error */
}
void ti_closeport(void )
{
ti_initport();
if ( ! debug_mode )
{
#if HARD_VERSION == HARD_VERSION_SER
if ( state & STATE_DEV )
CloseDevice((struct IORequest *)SerialIO);
if ( state & STATE_EXTIO )
DeleteExtIO((struct IORequest *)SerialIO);
if ( state & STATE_PORT )
DeletePort(SerialMP);
#elif HARD_VERSION == HARD_VERSION_PAR
if ( state & STATE_DEV )
CloseDevice((struct IORequest *)ParallelIO);
if ( state & STATE_EXTIO )
DeleteExtIO((struct IORequest *)ParallelIO);
if ( state & STATE_PORT )
DeletePort(ParallelMP);
#endif
}
timer_delete(&time_info);
state = 0;
}
inline void ti_setline(int value, UBYTE where)
{
#if HARD_VERSION == HARD_VERSION_SER
if ( where == LINE1 )
where = CIAF_COMRTS;
else
where = CIAF_COMDTR;
if ( value == LOW )
ciab.ciapra=ciab.ciapra|where;
else
ciab.ciapra=ciab.ciapra&(where^0xFF);
#elif HARD_VERSION == HARD_VERSION_PAR
if ( where == LINE1 )
where = 2;
else
where = 1;
if ( value == HIGH )
ciaa.ciaprb|=where;
else
ciaa.ciaprb&=(where^0xFF);
#endif
}
inline UBYTE ti_getline(UBYTE where)
{
#if HARD_VERSION == HARD_VERSION_SER
if ( where == LINE1 )
where = CIAF_COMCTS;
else
where = CIAF_COMDSR;
if ( ciab.ciapra&where )
return(LOW);
else
return(HIGH);
#elif HARD_VERSION == HARD_VERSION_PAR
if ( where == LINE1 )
where = CIAF_PRTRSEL;
else
where = CIAF_PRTRPOUT;
if ( ciab.ciapra&where )
return(HIGH);
else
return(LOW);
#endif
}
inline void ti_initport(void )
{
#if HARD_VERSION == HARD_VERSION_SER
ti_setline(HIGH,LINE1);
ti_setline(HIGH,LINE2);
ciaa.ciaddrb = 0xc0;
#elif HARD_VERSION == HARD_VERSION_PAR
ciaa.ciaddrb = 0x03;
ciab.ciaddra = 0x00;
ti_setline(HIGH,LINE1);
ti_setline(HIGH,LINE2);
#endif
}
inline int ti_sendbit(UBYTE bit )
{
int where1, where2;
unsigned long int count;
if ( bit )
{
where1 = LINE2;
where2 = LINE1;
}
else
{
where1 = LINE1;
where2 = LINE2;
}
ti_setline(LOW,where1);
count=0;
do
{ if ( ++count >= HARD_MAX_TRY_ACTIVE )
WAIT_RETR;
}
while ( ti_getline(where2) != LOW && count <= HARD_MAX_TRY );
if ( count > HARD_MAX_TRY )
{
#ifdef DEBUG
printf(__FILE__"> sendbit Timeout send 1 (%ld)\n",count);
#endif
WAIT_TIMEOUT;
return(HARD_TIMEOUT);
}
#ifdef STAT
printf(__FILE__"> sendbit Acquittement recu , count=%ld\n",count);
#endif
ti_setline(HIGH,where1);
count = 0;
do
{ if ( ++count >= HARD_MAX_TRY_ACTIVE )
WAIT_RETR;
}
while ( ti_getline(where2) != HIGH && count <= HARD_MAX_TRY );
#ifdef STAT
printf(__FILE__"> sendbit Fin acquittement recu , count=%ld\n",count);
#endif
if ( count > HARD_MAX_TRY )
{
#ifdef DEBUG
printf(__FILE__"> sendbit Timeout send 2 (%ld)\n",count);
#endif
WAIT_TIMEOUT;
return(HARD_TIMEOUT);
}
return(0);
}
inline int ti_recvbit(UBYTE *result )
{
unsigned long int count,count2;
count2 = 0;
do
{
if ( ti_getline(LINE1) == LOW )
{
#ifdef STAT
printf(__FILE__"> recvbit CTS==LOW count=%ld\n",count2);
#endif
ti_setline(LOW,LINE2);
count=0;
do
{ if ( ++ count >= HARD_MAX_TRY_ACTIVE )
WAIT_RETR;
}
while ( ti_getline(LINE1) == LOW && count <= HARD_MAX_TRY );
ti_setline(HIGH,LINE2);
/* We just make sure that our previous order is on the line : */
count = 0;
do {count++;}while(ti_getline(LINE2)!=HIGH&&count<HARD_MAX_TRY_ACTIVE);
*result = 0;
if ( count > HARD_MAX_TRY )
{
#ifdef DEBUG
printf(__FILE__"> Timeout recv A (%ld)\n",count);
#endif
WAIT_TIMEOUT;
return(HARD_TIMEOUT);
}
return(0);
}
if ( ti_getline(LINE2) == LOW )
{
#ifdef STAT
printf(__FILE__"> recvbit DSR==LOW count=%ld\n",count2);
#endif
ti_setline(LOW,LINE1);
count=0;
do
{
if ( ++count >= HARD_MAX_TRY_ACTIVE )
WAIT_RETR;
}
while ( ti_getline(LINE2) == LOW && count <= HARD_MAX_TRY );
ti_setline(HIGH,LINE1);
count = 0;
do {count++;} while(ti_getline(LINE1)!=HIGH&&count<HARD_MAX_TRY_ACTIVE);
#ifdef STAT
printf(__FILE__"> recvbit result=1, count=%ld\n",count);
#endif
*result = 1;
if ( count > HARD_MAX_TRY )
{
#ifdef DEBUG
printf(__FILE__"> rB%ld\n",count);
printf(__FILE__"> Timeout recv B (%ld)\n",count);
#endif
WAIT_TIMEOUT;
return(HARD_TIMEOUT);
}
return(0);
}
/*if ( count2 >= HARD_MAX_TRY_ACTIVE )
WAIT_RETR;*/
count2++;
}
while(count2<100*HARD_MAX_TRY);
#ifdef DEBUG
printf(__FILE__"> Timeout recv C (%ld)\n",count2);
#endif
ti_initport();
//WAIT_TIMEOUT;
return(HARD_TIMEOUT);
}
int ti_recvbyte(UBYTE *result )
{
int cpt;
UBYTE temp;
*result=0;
for ( cpt=0; cpt<BITS_PER_BYTE; cpt++)
{
if ( ti_recvbit(&temp) == HARD_TIMEOUT )
{
#ifdef DEBUG
printf("bytes.c> Error (r) on bit %d\n",cpt);
#endif
return(BYTE_ERROR);
}
#ifdef LOG
//printf("%d",temp);
#endif
*result=*result | ( temp << cpt );
}
#ifdef DEBUG
if ( isalpha(*result) )
printf("Log> Got %2X (%c)\n",*result,*result);
else
printf("Log> Got %2X\n",*result);
#endif
//WAIT_RETR;
return(0);
}
int ti_sendbyte(UBYTE byte)
{
int cpt=0;
#ifdef DEBUG
if ( isalpha(byte) )
printf("Log> Put %2X (%c)\n",byte,byte);
else
printf("Log> Put %2X\n",byte);
#endif
for ( cpt=0; cpt<BITS_PER_BYTE; cpt++)
{
//printf("%d",byte&1);
if ( ti_sendbit( byte & 1 ) == HARD_TIMEOUT )
{
#ifdef DEBUG
printf("bytes.c> Erreur (s) sur le bit %d\n",cpt);
#endif
return(BYTE_ERROR);
}
byte = byte >> 1;
}
//WAIT_RETR;
return(0);
}
int ti_sendbytes(UBYTE *bytes,int nb)
{
int cpt;
for ( cpt=0; cpt<nb; cpt++)
{
if ( ti_sendbyte(bytes[cpt]) == BYTE_ERROR )
return(BYTE_ERROR);
}
return(0);
}